package com.chen.function_demo.chapter1;

import java.util.ArrayList;
import java.util.List;

/**
 * 第一章第一节
 * @author 陈哲<p>
 * ================================<p>
 * Date: 2025/5/11<p>
 * Time: 17:30<p>
 * ================================
 */
public class Section1 {
    /*
        1.1 什么是合格的函数
        （1）输入不变，输出不变
        （2）如果引用外部变量，则外部变量应不可变
     */
    // 普通的函数
    public static int add(int a, int b) {
        return a + b;
    }
    // 函数式接口
    @FunctionalInterface
    interface Lambda {
        int calculate(int a, int b);
    }
    // 将函数化为对象
    Lambda add = (a, b) -> a + b;
    /*
        前者是纯粹的两数相加的函数，要使用它需要通过SectionOne.add(a,b)找到它，然后执行
        后者是函数式接口，位置是可变的，哪里需要就可以将其传递到哪使用
        接口的目的是为了将来用它执行函数对象，此接口只能定义一个方法
     */
    /**
     * 定义一个学生类
     * @param name
     * @param score
     * @param age
     */
    record Student(String name, int score, int age){}

    public static void main(String[] args) {
        // 函数对象好处:行为参数化 看下面的例子
        List<Student> students = List.of(
                new Student("张三", 100, 18),
                new Student("李四", 90, 19),
                new Student("王五", 50, 16)
        );
        //需求1: 获取所有学生成绩大于60分的学生并打印 （常规思路：创建一个方法，筛选60分以上的学生studentFilterScore）
        studentFilterScore(students).forEach(System.out::println);
        //需求2: 获取所有学生年龄小于18岁的学生并打印（常规思路：创建一个方法，筛选年龄在18以下的学生studentFilterAge）
        studentFilterAge(students).forEach(System.out::println);
        /*
            需求1和需求2的实现方法中代码几乎完全一样，只是筛选条件不同，造成大量重复代码
            这个时候，如果我们将判断的行为参数化，那么我们就可以减少大量重复代码。
            定义一个函数式接口，在创建一个配套的方法studentFilter
         */
        // 将大于60分的判断行为创建为一个函数对象
        StudentFilter studentFilter =(Student student) -> student.score > 60;
        // 将小于18岁的判断行为创建为一个函数对象
        StudentFilter studentFilterAge = (Student student) -> student.age < 18;
        // 需求1: 获取所有学生成绩大于60分
        studentFilter(students, studentFilter).forEach(System.out::println);
        // 需求2: 获取所有学生年龄小于18岁的学生
        studentFilter(students, studentFilterAge).forEach(System.out::println);
    }

    // 定义行为函数筛选学生
    interface StudentFilter {
        boolean filter(Student student);
    }
    static List<Student> studentFilterScore(List<Student> students) {
        List<Student> result = new ArrayList<>();
        for (Student student : students) {
            if (student.score > 60) {
                result.add(student);
            }
        }
        return result;
    }

    static List<Student> studentFilterAge(List<Student> students) {
        List<Student> result = new ArrayList<>();
        for (Student student : students) {
            if (student.age < 18) {
                result.add(student);
            }
        }
        return result;
    }
    static List<Student> studentFilter(List<Student> students, StudentFilter filter) {
        List<Student> result = new ArrayList<>();
        for (Student student : students) {
            //  将定义好的行为，传入到方法中
            if (filter.filter(student)) {
                result.add(student);
            }
        }
        return result;
    }

}
